from es import exists, entitysetvalue, entitygetvalue, setplayerprop, setindexprop, fire, createentity, getplayerhandle, getindexfromhandle, addons, server, playsound
from weaponlib import getWeapon
from playerlib import getPlayer as pgetPlayer
from gamethread import delayedname, cancelDelayed
from random import randint

__all__ = ['getPlayer']

moduleName = __import__(__name__)

class getPlayer(object):
    userid = 0
    settings = {}

    def __init__(self, userid):
        self.userid = str(userid)
        if not exists('userid', self.userid):
            raise KeyError, 'Player ' + self.userid + 'doesn\'t exist.'

        if not self.userid in players:
            players[self.userid] = {'gravity':1.0, 'drunk':False, 'poison':False, 'regen':False}

        self.settings = players[self.userid]

    def __getattr__(self, attr):
        if hasattr(getPlayer, attr):
            return getattr(self, attr)

        else:
            try:
                return self.__getitem__(attr)

            except KeyError:
                raise AttributeError, attr

    def __setattr__(self, attr, value):
        if hasattr(getPlayer, attr):
            object.__setattr__(self, attr, value)

        else:
            try:
                self.__setitem__(attr, value)

            except KeyError:
                raise AttributeError, attr

    def __getitem__(self, attr):
        if attr == 'index':
            return self.getIndex()

        elif attr == 'gravity':
            return self.getGravity()

        elif attr == 'drunk':
            return self.getDrunk()

        elif attr == 'regen':
            return self.getRegen()

        elif attr == 'poison':
            return self.getPoison()

        raise KeyError, attr

    def __setitem__(self, attr, value):
        if attr == 'gravity':
            self.setGravity(value)

        elif attr == 'drunk':
            self.setDrunk(value)

        elif attr == 'regen':
            self.setRegen(value)

        elif attr == 'poison':
            self.setPoison(value)

        elif attr == 'burn':
            self.setBurn(value)

        else:
            raise KeyError, attr

    def getIndex(self):
        return getindexfromhandle(getplayerhandle(self.userid))

    def getGravity(self):
        return self.settings['gravity']

    def getPoison(self):
        return self.settings['poison']

    def getDrunk(self):
        return self.settings['drunk']

    def getRegen(self):
        return self.settings['regen']

    def setDrunk(self, value):
        if value:
            self.settings['drunk'] = True

        else:
            self.settings['drunk'] = False

    def setPoison(self, value):
        if value:
            self.settings['poison'] = True

        else:
            self.settings['poison'] = False

    def setRegen(self, value):
        if value:
            self.settings['regen'] = True

        else:
            self.settings['regen'] = False

    def setGravity(self, amount):
        amount = round(float(amount), 2)
        self.settings['gravity'] = amount
        fire(self.userid, '!self', 'addoutput', 'gravity ' + str(amount))

    def setBurn(self, duration):
        fire(self.userid, '!self', 'IgniteLifetime', duration)

    def damagePlayer(self, damage, damagetype=32, userid=None, weapon='point_hurt'):
        if not userid:
            userid = self.userid

        index = self.getIndex()
        oldName = entitygetvalue(index, 'targetname')
        entitysetvalue(index, 'targetname', index)
        entity = createentity('point_hurt')
        entitysetvalue(entity, 'classname', weapon)
        entitysetvalue(entity, 'targetname', entity)
        entitysetvalue(entity, 'damage', damage)
        entitysetvalue(entity, 'damagetype', damagetype)
        entitysetvalue(entity, 'damagetarget', index)
        setindexprop(entity, 'CBaseEntity.m_hOwnerEntity', getplayerhandle(userid))
        fire(userid, entity, 'Hurt')
        fire(userid, entity, 'Kill')
        fire(self.userid, '!self', 'addoutput', 'targetname ' + oldName)

    def respawnPlayer(self):
        if pgetPlayer(self.userid).isdead:
            setplayerprop(self.userid, 'CCSPlayer.m_iPlayerState', 0)
            setplayerprop(self.userid, 'CBasePlayer.m_lifeState', 512)

        server.queuecmd('es_xspawnplayer ' + self.userid)

    def stripPlayer(self):
        index = createentity('player_weaponstrip')
        entitysetvalue(index, 'targetname', index)
        fire(self.userid, index, 'Strip')
        fire(self.userid, index, 'Kill')

    def givePlayer(self, entity):
        index = createentity(entity)
        weapon = getWeapon(entity)
        if weapon:
            if weapon.maxammo:
                setindexprop(index, 'CBaseCombatWeapon.LocalWeaponData.m_iClip2', weapon.maxammo)

        entitysetvalue(index, 'origin', entitygetvalue(self.getIndex(), 'origin'))
        server.queuecmd('es_xspawnentity ' + str(index))

def repeatLoop():
    for userid in players:
        if not exists('userid', userid):
            continue

        player = getPlayer(userid)
        pplayer = pgetPlayer(userid)
        if players[userid]['drunk']:
            setplayerprop(userid, 'CBasePlayer.localdata.m_Local.m_vecPunchAngle', '0' + ',' + '0' + ',' + str(randint(-100, 100)))

        if players[userid]['regen']:
            if pplayer.health < 100:
                pplayer.health += 1

        if players[userid]['poison']:
            if pplayer.health > 1:
                pplayer.health -= 1
                playsound(userid, 'player/headshot1.wav', 1.0)

            else:
                player.damagePlayer(pplayer.health)

    delayedname(1, '_superdice_repeat_loop', repeatLoop, ())

def player_disconnect(ev):
    userid = ev['userid']
    if not userid in players:
        return

    del players[userid]

def player_jump(ev):
    player = getPlayer(ev['userid'])
    player.setGravity(player.getGravity())

def player_spawn(ev):
    player = getPlayer(ev['userid'])
    player.setGravity(1.0)
    player.setDrunk(False)
    player.setRegen(False)
    player.setPoison(False)

def player_death(ev):
    player = getPlayer(ev['userid'])
    player.setDrunk(False)
    player.setRegen(False)
    player.setPoison(False)

def es_map_start(ev):
    players.clear()
    cancelDelayed('_superdice_repeat_loop')
    repeatLoop()

addons.registerForEvent(moduleName, 'player_jump', player_jump)
addons.registerForEvent(moduleName, 'player_spawn', player_spawn)
addons.registerForEvent(moduleName, 'player_death', player_death)
addons.registerForEvent(moduleName, 'es_map_start', es_map_start)

players = {}

cancelDelayed('_superdice_repeat_loop')
repeatLoop()
